﻿using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

namespace Sissonix.ExtRest
{
    public static class RestHelper
    {
        public static string FormatObjectResponse<T>(T obj, ExtRest.ResponseFormat fmt)
        {
            if (obj == null)
                return "";

            //IMPORTANT ASSUMPTION: When we are returning one single object, it is likely becuase
            //we are loading a form.  When load a form, you cannot return an array of objects. The
            //Ext.form.BasicForm.load() method expects a single JSON object, not an array.
            
            //TODO: the fmt param is ignore, always JSON
            try
            {
                string json = RestHelper.Serialize(obj, true);
                return "{success:true, data:" + json + "}";
            }
            catch (System.Exception e)
            {
                return "{success:false, error: " + e.Message + "}";

            }
            /* this was the old code that made the single object an array with length=1           
            List<T> list = new List<T>();
            list.Add(obj);
            return ExtRest.RestHelper.FormatListResponse(list, fmt, 0);
            */
        }

        public static string FormatListResponse<T>(IList<T> list, ExtRest.ResponseFormat fmt)
        {
            return ExtRest.RestHelper.FormatListResponse(list, fmt, 0);
        }

        public static string FormatListResponse<T>(IList<T> list, ExtRest.ResponseFormat? fmt, int totalCount)
        {
            if (list == null || list.Count == 0) 
                return "";

            //TODO: the fmt param is ignore, always JSON
            try
            {
                string json = RestHelper.Serialize(list, true);
                if (totalCount > 0)
                    return "{success:true, totalcount:" + totalCount.ToString() + 
                        ", data:" + json + "}";
                else
                    return "{success:true, data:" + json + "}";
            }
            catch (System.Exception e)
            {
                return "{success:false, error: " + e.Message + "}";

            }
        }

        public static string FormatErrorResponse(string msg)
        {
            return "{success:false, error: " + msg + "}";
        }

        public static string Serialize(object value, bool formatted)
        {
            Type type = value.GetType();

            Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();

            json.NullValueHandling = NullValueHandling.Ignore;

            json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
            json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
            json.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;


            StringWriter sw = new StringWriter();
            Newtonsoft.Json.JsonTextWriter writer = new JsonTextWriter(sw);
            if (formatted)
                writer.Formatting = Formatting.Indented;
            else
                writer.Formatting = Formatting.None;

            writer.QuoteChar = '"';
            json.Serialize(writer, value);

            string output = sw.ToString();
            writer.Close();
            sw.Close();

            return output;
        }

        public static object Deserialize(string jsonText, Type valueType)
        {
            Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();

            json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
            json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
            json.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

            StringReader sr = new StringReader(jsonText);
            Newtonsoft.Json.JsonTextReader reader = new JsonTextReader(sr);
            object result = json.Deserialize(reader, valueType);
            reader.Close();

            return result;
        }
    }
}
